suppressPackageStartupMessages(library(tidyverse))
library(gapminder)
Saving Graphs to File
- Don’t use the mouse
- Use
ggsave for ggplot
- Practice by saving the following plot to file:
p <- ggplot(mtcars, aes(hp, wt)) +
geom_point()
ggsave("my_plot.png", p)
Saving 7 x 7 in image
- Base R way: print plots “to screen”, sandwiched between
pdf()/jpeg()/png()… and dev.off().
- Vector vs. raster: Images are stored on your computer as either vector or raster.
Scales; Colour
Scale functions in ggplot2 take the form scale_[aesthetic]_[mapping]().
Let’s first focus on the following plot:
p_scales <- ggplot(gapminder, aes(gdpPercap, lifeExp)) +
geom_point(aes(colour=pop), alpha=0.2)
p_scales +
scale_x_log10() +
scale_colour_continuous(trans="log10")

- Change the y-axis tick mark spacing to 10; change the colour spacing to include all powers of 10.
p_scales +
scale_x_log10() +
scale_colour_continuous(
trans = "log10",
breaks = 10^(1:10)
) +
scale_y_continuous(breaks=1:10 * 10)

- Specify
scales::*_format in the labels argument of a scale function to do the following:
- Change the x-axis labels to dollar format (use
scales::dollar_format())
- Change the colour labels to comma format (use
scales::comma_format())
library(scales)
p_scales +
scale_x_log10(labels=dollar_format()) +
scale_colour_continuous(
trans = "log10",
breaks = 10^(1:10),
labels = comma_format()
) +
scale_y_continuous(breaks=10*(1:10))

- Use
RColorBrewer to change the colour scheme.
- Notice the three different types of scales: sequential, diverging, and continuous.
## All palettes the come with RColorBrewer:
RColorBrewer::display.brewer.all()

p_scales +
scale_x_log10(labels=dollar_format()) +
scale_color_distiller(
trans = "log10",
breaks = 10^(1:10),
labels = comma_format(),
palette = "Greens"
) +
scale_y_continuous(breaks=10*(1:10))

- Use
viridis to change the colour to a colour-blind friendly scheme
- Hint: add
scale_colour_viridis_c (c stands for continuous; d discrete).
- You can choose a palette with
option.
p_scales +
scale_x_log10(labels=dollar_format()) +
scale_colour_viridis_c(
trans = "log10",
breaks = 10^(1:10),
labels = comma_format(),
# palette = comma_format()
) +
scale_y_continuous(breaks=10*(1:10))

Theming
Changing the look of a graphic can be achieved through the theme() layer.
There are “complete themes” that come with ggplot2, my favourite being theme_bw (I’ve grown tired of the default gray background, so theme_bw is refreshing).
- Change the theme of the following plot to
theme_bw():
ggplot(iris, aes(Sepal.Width, Sepal.Length)) +
facet_wrap(~ Species) +
geom_point() +
labs(x = "Sepal Width",
y = "Sepal Length",
title = "Sepal sizes of three plant species") +
theme_bw()

- Then, change font size of axis labels, and the strip background colour. Others?
ggplot(iris, aes(Sepal.Width, Sepal.Length)) +
facet_wrap(~ Species) +
geom_point() +
labs(x = "Sepal Width",
y = "Sepal Length",
title = "Sepal sizes of three plant species") +
theme_bw() +
theme(axis.text = element_text(size=16),
strip.background = element_rect(fill = "orange"),
panel.background = element_rect(fill = "blue"))

Plotly
Consider the following plot:
(p <- gapminder %>%
filter(continent != "Oceania") %>%
ggplot(aes(gdpPercap, lifeExp)) +
geom_point(aes(colour=pop), alpha=0.2) +
scale_x_log10(labels=dollar_format()) +
scale_colour_distiller(
trans = "log10",
breaks = 10^(1:10),
labels = comma_format(),
palette = "Greens"
) +
facet_wrap(~ continent) +
scale_y_continuous(breaks=10*(1:10)) +
theme_bw())

- Convert it to a
plotly object by applying the ggplotly() function:
library(plotly)
ggplotly(p)
- You can save a plotly graph locally as an html file. Try saving the above:
- NOTE: plotly graphs don’t seem to show up in Rmd notebooks, but they do with Rmd documents.
p %>%
ggplotly() %>%
htmlwidgets::saveWidget("LOCATION_GOES_HERE")
- Run this code to see the json format underneath:
p %>%
ggplotly() %>%
plotly_json()
- Check out code to make a plotly object from scratch using
plot_ly() – scatterplot of gdpPercap vs lifeExp.
plot_ly(gapminder,
x = ~gdpPercap,
y = ~lifeExp,
type = "scatter",
mode = "markers",
opacity = 0.2) %>%
layout(xaxis = list(type = "log"))
- Add population to form a z-axis for a 3D plot:
plot_ly(gapminder,
x = ~gdpPercap,
y = ~lifeExp,
z = ~pop,
type = "scatter3d",
mode = "markers",
opacity = 0.2)
LS0tCnRpdGxlOiAiY20wMTMgRXhlcmNpc2UiCm91dHB1dDogaHRtbF9ub3RlYm9vawplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCmBgYHtyfQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UpKQpsaWJyYXJ5KGdhcG1pbmRlcikKYGBgCgoKIyBTYXZpbmcgR3JhcGhzIHRvIEZpbGUKCi0gRG9uJ3QgdXNlIHRoZSBtb3VzZQotIFVzZSBgZ2dzYXZlYCBmb3IgZ2dwbG90CiAgICAtIFByYWN0aWNlIGJ5IHNhdmluZyB0aGUgZm9sbG93aW5nIHBsb3QgdG8gZmlsZTogCgpgYGB7cn0KcCA8LSBnZ3Bsb3QobXRjYXJzLCBhZXMoaHAsIHd0KSkgKyAKICAgIGdlb21fcG9pbnQoKQpnZ3NhdmUoIm15X3Bsb3QucG5nIiwgcCkKYGBgCgotIEJhc2UgUiB3YXk6IHByaW50IHBsb3RzICJ0byBzY3JlZW4iLCBzYW5kd2ljaGVkIGJldHdlZW4gYHBkZigpYC9ganBlZygpYC9gcG5nKClgLi4uIGFuZCBgZGV2Lm9mZigpYC4gCi0gVmVjdG9yIHZzLiByYXN0ZXI6IEltYWdlcyBhcmUgc3RvcmVkIG9uIHlvdXIgY29tcHV0ZXIgYXMgZWl0aGVyIF92ZWN0b3JfIG9yIF9yYXN0ZXJfLgogICAgLSBfX1Jhc3Rlcl9fOiBhbiBgbmAgYnkgYG1gIGdyaWQgb2YgcGl4ZWxzLCBlYWNoIHdpdGggaXRzIG93biBjb2xvdXIuIGBqcGVnYCwgYHBuZ2AsIGBnaWZgLCBgYm1wYC4KICAgIC0gX19WZWN0b3JfXzogcmVwcmVzZW50ZWQgYXMgc2hhcGVzIGFuZCBsaW5lcy4gYHBkZmAsIFtgc3ZnYF0oaHR0cHM6Ly93d3cudzNzY2hvb2xzLmNvbS9ncmFwaGljcy9zdmdfaW50cm8uYXNwKS4KICAgIC0gRm9yIHRpcHM6IFsiMTAgdGlwcyBmb3IgbWFraW5nIHlvdXIgUiBncmFwaGljcyBsb29rIHRoZWlyIGJlc3QiIl0oaHR0cDovL2Jsb2cucmV2b2x1dGlvbmFuYWx5dGljcy5jb20vMjAwOS8wMS8xMC10aXBzLWZvci1tYWtpbmcteW91ci1yLWdyYXBoaWNzLWxvb2stdGhlaXItYmVzdC5odG1sKS4KICAgIAojIFNjYWxlczsgQ29sb3VyCgpTY2FsZSBmdW5jdGlvbnMgaW4gYGdncGxvdDJgIHRha2UgdGhlIGZvcm0gYHNjYWxlX1thZXN0aGV0aWNdX1ttYXBwaW5nXSgpYC4KCkxldCdzIGZpcnN0IGZvY3VzIG9uIHRoZSBmb2xsb3dpbmcgcGxvdDoKCmBgYHtyfQpwX3NjYWxlcyA8LSBnZ3Bsb3QoZ2FwbWluZGVyLCBhZXMoZ2RwUGVyY2FwLCBsaWZlRXhwKSkgKwogICAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1wb3ApLCBhbHBoYT0wLjIpCnBfc2NhbGVzICsgCiAgICBzY2FsZV94X2xvZzEwKCkgKwogICAgc2NhbGVfY29sb3VyX2NvbnRpbnVvdXModHJhbnM9ImxvZzEwIikKYGBgCgoxLiBDaGFuZ2UgdGhlIHktYXhpcyB0aWNrIG1hcmsgc3BhY2luZyB0byAxMDsgY2hhbmdlIHRoZSBjb2xvdXIgc3BhY2luZyB0byBpbmNsdWRlIGFsbCBwb3dlcnMgb2YgMTAuCgpgYGB7cn0KcF9zY2FsZXMgKwogICAgc2NhbGVfeF9sb2cxMCgpICsKICAgIHNjYWxlX2NvbG91cl9jb250aW51b3VzKAogICAgICAgIHRyYW5zICA9ICJsb2cxMCIsIAogICAgICAgIGJyZWFrcyA9IDEwXigxOjEwKQogICAgKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPTE6MTAgKiAxMCkKYGBgCgoyLiBTcGVjaWZ5IGBzY2FsZXM6OipfZm9ybWF0YCBpbiB0aGUgYGxhYmVsc2AgYXJndW1lbnQgb2YgYSBzY2FsZSBmdW5jdGlvbiB0byBkbyB0aGUgZm9sbG93aW5nOgogICAgLSBDaGFuZ2UgdGhlIHgtYXhpcyBsYWJlbHMgdG8gZG9sbGFyIGZvcm1hdCAodXNlIGBzY2FsZXM6OmRvbGxhcl9mb3JtYXQoKWApCiAgICAtIENoYW5nZSB0aGUgY29sb3VyIGxhYmVscyB0byBjb21tYSBmb3JtYXQgKHVzZSBgc2NhbGVzOjpjb21tYV9mb3JtYXQoKWApCgpgYGB7cn0KbGlicmFyeShzY2FsZXMpCnBfc2NhbGVzICsKICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzPWRvbGxhcl9mb3JtYXQoKSkgKwogICAgc2NhbGVfY29sb3VyX2NvbnRpbnVvdXMoCiAgICAgICAgdHJhbnMgID0gImxvZzEwIiwgCiAgICAgICAgYnJlYWtzID0gMTBeKDE6MTApLAogICAgICAgIGxhYmVscyA9IGNvbW1hX2Zvcm1hdCgpCiAgICApICsKICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9MTAqKDE6MTApKQpgYGAKCjMuIFVzZSBgUkNvbG9yQnJld2VyYCB0byBjaGFuZ2UgdGhlIGNvbG91ciBzY2hlbWUuCiAgICAtIE5vdGljZSB0aGUgdGhyZWUgZGlmZmVyZW50IHR5cGVzIG9mIHNjYWxlczogc2VxdWVudGlhbCwgZGl2ZXJnaW5nLCBhbmQgY29udGludW91cy4KCmBgYHtyfQojIyBBbGwgcGFsZXR0ZXMgdGhlIGNvbWUgd2l0aCBSQ29sb3JCcmV3ZXI6ClJDb2xvckJyZXdlcjo6ZGlzcGxheS5icmV3ZXIuYWxsKCkKcF9zY2FsZXMgKwogICAgc2NhbGVfeF9sb2cxMChsYWJlbHM9ZG9sbGFyX2Zvcm1hdCgpKSArCiAgICBzY2FsZV9jb2xvcl9kaXN0aWxsZXIoCiAgICAgICAgdHJhbnMgICA9ICJsb2cxMCIsCiAgICAgICAgYnJlYWtzICA9IDEwXigxOjEwKSwKICAgICAgICBsYWJlbHMgID0gY29tbWFfZm9ybWF0KCksCiAgICAgICAgcGFsZXR0ZSA9ICJHcmVlbnMiCiAgICApICsKICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9MTAqKDE6MTApKQpgYGAKCjQuIFVzZSBgdmlyaWRpc2AgdG8gY2hhbmdlIHRoZSBjb2xvdXIgdG8gYSBjb2xvdXItYmxpbmQgZnJpZW5kbHkgc2NoZW1lCiAgICAtIEhpbnQ6IGFkZCBgc2NhbGVfY29sb3VyX3ZpcmlkaXNfY2AgKGBjYCBzdGFuZHMgZm9yIGNvbnRpbnVvdXM7IGBkYCBkaXNjcmV0ZSkuCiAgICAtIFlvdSBjYW4gY2hvb3NlIGEgcGFsZXR0ZSB3aXRoIGBvcHRpb25gLgoKYGBge3J9CnBfc2NhbGVzICsKICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzPWRvbGxhcl9mb3JtYXQoKSkgKwogICAgc2NhbGVfY29sb3VyX3ZpcmlkaXNfYygKICAgICAgICB0cmFucyAgID0gImxvZzEwIiwKICAgICAgICBicmVha3MgID0gMTBeKDE6MTApLAogICAgICAgIGxhYmVscyAgPSBjb21tYV9mb3JtYXQoKSwKICAgICAgICAjIHBhbGV0dGUgPSBjb21tYV9mb3JtYXQoKQogICAgKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPTEwKigxOjEwKSkKYGBgCgojIFRoZW1pbmcKCkNoYW5naW5nIHRoZSBsb29rIG9mIGEgZ3JhcGhpYyBjYW4gYmUgYWNoaWV2ZWQgdGhyb3VnaCB0aGUgYHRoZW1lKClgIGxheWVyLgoKVGhlcmUgYXJlIFsiY29tcGxldGUgdGhlbWVzIl0oaHR0cDovL2dncGxvdDIudGlkeXZlcnNlLm9yZy9yZWZlcmVuY2UvZ2d0aGVtZS5odG1sKSB0aGF0IGNvbWUgd2l0aCBgZ2dwbG90MmAsIG15IGZhdm91cml0ZSBiZWluZyBgdGhlbWVfYndgIChJJ3ZlIGdyb3duIHRpcmVkIG9mIHRoZSBkZWZhdWx0IGdyYXkgYmFja2dyb3VuZCwgc28gYHRoZW1lX2J3YCBpcyByZWZyZXNoaW5nKS4KCjEuIENoYW5nZSB0aGUgdGhlbWUgb2YgdGhlIGZvbGxvd2luZyBwbG90IHRvIGB0aGVtZV9idygpYDoKCmBgYHtyfQpnZ3Bsb3QoaXJpcywgYWVzKFNlcGFsLldpZHRoLCBTZXBhbC5MZW5ndGgpKSArCiAgICAgZmFjZXRfd3JhcCh+IFNwZWNpZXMpICsKICAgICBnZW9tX3BvaW50KCkgKwogICAgIGxhYnMoeCA9ICJTZXBhbCBXaWR0aCIsCiAgICAgICAgICB5ID0gIlNlcGFsIExlbmd0aCIsCiAgICAgICAgICB0aXRsZSA9ICJTZXBhbCBzaXplcyBvZiB0aHJlZSBwbGFudCBzcGVjaWVzIikgKwogICAgdGhlbWVfYncoKQpgYGAKCjIuIFRoZW4sIGNoYW5nZSBmb250IHNpemUgb2YgYXhpcyBsYWJlbHMsIGFuZCB0aGUgc3RyaXAgYmFja2dyb3VuZCBjb2xvdXIuIE90aGVycz8KCmBgYHtyfQpnZ3Bsb3QoaXJpcywgYWVzKFNlcGFsLldpZHRoLCBTZXBhbC5MZW5ndGgpKSArCiAgICAgZmFjZXRfd3JhcCh+IFNwZWNpZXMpICsKICAgICBnZW9tX3BvaW50KCkgKwogICAgIGxhYnMoeCA9ICJTZXBhbCBXaWR0aCIsCiAgICAgICAgICB5ID0gIlNlcGFsIExlbmd0aCIsCiAgICAgICAgICB0aXRsZSA9ICJTZXBhbCBzaXplcyBvZiB0aHJlZSBwbGFudCBzcGVjaWVzIikgKwogICAgdGhlbWVfYncoKSArCiAgICB0aGVtZShheGlzLnRleHQgID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLAogICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIm9yYW5nZSIpLAogICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJsdWUiKSkKYGBgCgoKIyBQbG90bHkKCkNvbnNpZGVyIHRoZSBmb2xsb3dpbmcgcGxvdDoKCmBgYHtyfQoocCA8LSBnYXBtaW5kZXIgJT4lIAogICAgIGZpbHRlcihjb250aW5lbnQgIT0gIk9jZWFuaWEiKSAlPiUgCiAgICAgZ2dwbG90KGFlcyhnZHBQZXJjYXAsIGxpZmVFeHApKSArCiAgICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPXBvcCksIGFscGhhPTAuMikgKwogICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzPWRvbGxhcl9mb3JtYXQoKSkgKwogICAgIHNjYWxlX2NvbG91cl9kaXN0aWxsZXIoCiAgICAgICAgIHRyYW5zICAgPSAibG9nMTAiLAogICAgICAgICBicmVha3MgID0gMTBeKDE6MTApLAogICAgICAgICBsYWJlbHMgID0gY29tbWFfZm9ybWF0KCksCiAgICAgICAgIHBhbGV0dGUgPSAiR3JlZW5zIgogICAgICkgKwogICAgIGZhY2V0X3dyYXAofiBjb250aW5lbnQpICsKICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPTEwKigxOjEwKSkgKwogICAgIHRoZW1lX2J3KCkpCmBgYAoKMS4gQ29udmVydCBpdCB0byBhIGBwbG90bHlgIG9iamVjdCBieSBhcHBseWluZyB0aGUgYGdncGxvdGx5KClgIGZ1bmN0aW9uOgoKYGBge3J9CmxpYnJhcnkocGxvdGx5KQpnZ3Bsb3RseShwKQpgYGAKCjIuIFlvdSBjYW4gc2F2ZSBhIHBsb3RseSBncmFwaCBsb2NhbGx5IGFzIGFuIGh0bWwgZmlsZS4gVHJ5IHNhdmluZyB0aGUgYWJvdmU6CiAgICAtIE5PVEU6IHBsb3RseSBncmFwaHMgZG9uJ3Qgc2VlbSB0byBzaG93IHVwIGluIFJtZCBfbm90ZWJvb2tzXywgYnV0IHRoZXkgZG8gd2l0aCBSbWQgX2RvY3VtZW50c18uCgpgYGB7cn0KcCAlPiUgCiAgICBnZ3Bsb3RseSgpICU+JSAKICAgIGh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KCJMT0NBVElPTl9HT0VTX0hFUkUiKQpgYGAKCgozLiBSdW4gdGhpcyBjb2RlIHRvIHNlZSB0aGUganNvbiBmb3JtYXQgdW5kZXJuZWF0aDoKCmBgYHtyfQpwICU+JSAKICAgIGdncGxvdGx5KCkgJT4lIAogICAgcGxvdGx5X2pzb24oKQpgYGAKCgo0LiBDaGVjayBvdXQgY29kZSB0byBtYWtlIGEgcGxvdGx5IG9iamVjdCBmcm9tIHNjcmF0Y2ggdXNpbmcgYHBsb3RfbHkoKWAgLS0gc2NhdHRlcnBsb3Qgb2YgZ2RwUGVyY2FwIHZzIGxpZmVFeHAuCiAgICAtIENoZWNrIG91dCB0aGUgW2NoZWF0IHNoZWV0XShodHRwczovL2ltYWdlcy5wbG90Lmx5L3Bsb3RseS1kb2N1bWVudGF0aW9uL2ltYWdlcy9yX2NoZWF0X3NoZWV0LnBkZikuCgpgYGB7cn0KcGxvdF9seShnYXBtaW5kZXIsIAogICAgICAgIHggPSB+Z2RwUGVyY2FwLCAKICAgICAgICB5ID0gfmxpZmVFeHAsIAogICAgICAgIHR5cGUgPSAic2NhdHRlciIsCiAgICAgICAgbW9kZSA9ICJtYXJrZXJzIiwKICAgICAgICBvcGFjaXR5ID0gMC4yKSAlPiUgCiAgICBsYXlvdXQoeGF4aXMgPSBsaXN0KHR5cGUgPSAibG9nIikpCmBgYAoKNS4gQWRkIHBvcHVsYXRpb24gdG8gZm9ybSBhIHotYXhpcyBmb3IgYSAzRCBwbG90OgoKYGBge3J9CnBsb3RfbHkoZ2FwbWluZGVyLCAKICAgICAgICB4ID0gfmdkcFBlcmNhcCwgCiAgICAgICAgeSA9IH5saWZlRXhwLCAKICAgICAgICB6ID0gfnBvcCwKICAgICAgICB0eXBlID0gInNjYXR0ZXIzZCIsCiAgICAgICAgbW9kZSA9ICJtYXJrZXJzIiwKICAgICAgICBvcGFjaXR5ID0gMC4yKQpgYGAKCgoK